package com.strongbj.iot.devices.smarrack.response.handle;

import java.net.InetSocketAddress;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.alibaba.fastjson.JSON;
import com.strongbj.core.device.Device;
import com.strongbj.core.device.DeviceManager;
import com.strongbj.core.device.IDevice;
import com.strongbj.core.util.ByteUtil;
import com.strongbj.core.util.ContextUtils;
import com.strongbj.iot.devices.smarrack.common.DeviceChannelMap;
import com.strongbj.iot.devices.smarrack.message.SmarRackMQMessage;
import com.strongbj.iot.devices.smarrack.message.SmarRackMessage;
import com.strongbj.iot.devices.smarrack.response.entity.DeviceEntity;
import com.strongbj.iot.mq.producer.TopicSender;

import io.netty.channel.ChannelHandlerContext;

/**
 * 心跳处理
 * 
 * @author root
 *
 */
public class HeartbeatHandle extends WithResponseHandle {
	private static Logger logger = LogManager.getLogger(HeartbeatHandle.class.getName());
	private final static byte COMMAND_ID = (byte) 0xAD;
	private TopicSender topicSender = (TopicSender) ContextUtils.getBean("topicSender");
	private final static String HEARTBEAT_ACTION_CODE = "heartbeat"; // 心跳code
	private final static String DEVICE_ONLINE_ACTION_CODE = "device_online"; // 设备在线的code
	private final static String RFID_TYPE = "smarrack";

	private boolean isFirstHeartbeat = true; // 是否获取第一次心跳

	@Override
	public boolean isHandle(SmarRackMessage t) {
		if (t.getCommand() == COMMAND_ID) {
			return true;
		} else {
			return false;
		}
	}

	@Override
	void messageHandle(ChannelHandlerContext ctx, SmarRackMessage t) {
		String deviceCode = ByteUtil.byteArrToHexString(t.getDevId());
		logger.debug("数码人设备返回心跳 deviceCode=" + deviceCode);

		try { 
			if(this.isFirstHeartbeat) {
				recodeDeviceCode(ctx, deviceCode); // 记录设备编码到管理类
			}
		} finally {
			pushHeartbeatDataToMQ(deviceCode); // 推送数据到
			// 设备第一次发送心跳时，发送设备在线信息到MQ
			if (this.isFirstHeartbeat) {
				String ip = ((InetSocketAddress) ctx.channel().remoteAddress()).getAddress().getHostAddress();
				this.pushDeviceOnlineMessageToMQ(deviceCode, ip);
				this.isFirstHeartbeat = false;
			}
		}
	}

	/**
	 * 记录设备编码到管理类
	 * 
	 * @param ctx
	 * @param t
	 */
	private void recodeDeviceCode(ChannelHandlerContext ctx, String deviceCode) {
		DeviceChannelMap.getInstance().put(deviceCode, ctx.channel());

		// 设置设备编号
		String ip = ((InetSocketAddress) ctx.channel().remoteAddress()).getAddress().getHostAddress();
		IDevice dev = DeviceManager.getInstance().findDevice(ip);
		if (dev != null) {
			dev.setDeviceCode(deviceCode);
		} else {
			dev = new Device(deviceCode, ip);
			DeviceManager.getInstance().registerDevice(dev);
		}
	}

	/**
	 * 推送心跳数据到mq
	 */
	private void pushHeartbeatDataToMQ(String deviceCode) {
		SmarRackMQMessage mqMessage = new SmarRackMQMessage();
		mqMessage.setActioncode(HEARTBEAT_ACTION_CODE);
		mqMessage.setRfidtype(RFID_TYPE);
		mqMessage.setAwsPostdata(deviceCode);
		String json = JSON.toJSONString(mqMessage);
		topicSender.send("smarRackToService", json);
		logger.debug("上传心跳信息=" + json);
	}

	/**
	 * 推送设备联机信息到MQ
	 */
	private void pushDeviceOnlineMessageToMQ(String deviceCode, String ip) {
		SmarRackMQMessage mqMessage = new SmarRackMQMessage();
		mqMessage.setActioncode(DEVICE_ONLINE_ACTION_CODE);
		mqMessage.setRfidtype(RFID_TYPE);

		DeviceEntity dev = new DeviceEntity();
		dev.setDeviceCode(deviceCode);
		dev.setIp(ip);
		mqMessage.setAwsPostdata(dev);
		String json = JSON.toJSONString(mqMessage);
		topicSender.send("smarRackToService", json);
		logger.info("上传设备初始化在线信息=" + json);
	}
}
